__DefGroup FALU : [ALL]
  __Encoding
    field<12,  3> Pred pg = PT;
    field<15,  1> PModi pg.not = False;

__DefGroup F_ARITH : [FALU]
  __Encoding
    field<16,  8> Reg rd;
    field<24,  8> Reg ra;

    field<72,  1> SignModi ra.neg = False;
    field<73,  1> SignModi ra.abs = False;

    field<76,  1> FPFtz ftz = NoFTZ;
    field<77,  1> FPSat sat = NoSAT;
    field<78,  2> FPRound rnd = RN;

__DefOptype FADD : [F_ARITH]
  __Encoding
    field< 0,  8> Optype optype == FADD;

  __Syntax
```asm          
FADD{.FTZ}{.SAT}{.rnd} Rd, {-}{|}Ra{|}, {-}{|}SrcB{|}      $sched $req ;

.rnd = {.RN*, .RP, .RM, .RZ}
```

  __Description
执行2个输入浮点数的加法，即Rd = Ra + SrcB。

  __OperandInfo
Ra和Rd必须来源于GPR。

SrcB的来源可以是GPR、UR、F32Imm或cmem。

Ra和SrcB可以添加一个负号（-）前缀，表示取来源的相反数作为操作数。

Ra和SrcB也可以添加绝对值符号，表示取来源的绝对值作为操作数。
但如果SrcB来源于F32Imm，由于其值完全是字面上的，此时不再需要使用绝对值符号。

同时存在多种修饰符时，按照：先取绝对值，再取相反数的优先级次序结合。

  __ModifierInfo
.rnd可取.RN（默认值，可省略）、.RP、.RM和.RZ，表示计算结果的舍入模式：

| .rnd  | 舍入模式 |
|:--:|:---|
|.RN | 尾数四舍五入 |
|.RP | 尾数向正无穷方向舍入 |
|.RM | 尾数向负无穷方向舍入 |
|.RZ | 尾数向零（原点）舍入 |

可选修饰符.FTZ表示如果输入/输出中有非规格化浮点数（subnormal number），则将其转换为有符号0（即保持符号位不变，其他bit全部置0）。

可选修饰符.SAT表示将结果截断到[+0.0, 1.0]的范围。

  __Semantics
```asm
FADD.ftz.sat.rnd Rd, Ra, SrcB:
    // 根据.FTZ启用与否，正确处理输入含非规格化浮点数的情况
    if (.ftz == .FTZ) {
        // 将输入的非规格化数flush到有符号0之后在参与比较
        if (isSubnormal(Ra) == true) {
            Ra = signZero(Ra);
        }
        if (isSubnormal(SrcB) == true) {
            SrcB = signZero(SrcB);
        }
    }
    // 计算舍入前的精确求和
    t = Ra + SrcB;
    // 舍入到F32可表示的值
    Rd = roundToF32(t, .rnd);
    // 根据.sat，决定是否将输出饱和到[+0.0, 1.0]
    if (.sat == .SAT) {
        // NAN将被映射到0.0
        if (isNAN(Rd) == true) {
            Rd = 0.0f;
        } else {
            Rd = Rd < 0.0f ? 0.0f : Rd;
            Rd = Rd > 1.0f ? 1.0f : Rd;
        }
    } else if (isNAN(Rd) == true) {
        // 输出特殊的QNAN
        Rd[31:0] = 0x7FFFFFFF
    }
    // 正确处理输出中的非规格化数
    if (.ftz == .FTZ) {
        Rd = isSubnormal(Rd) ? signZero(Rd) : Rd;
    }
```

浮点加法中的特殊值，在遵守
[IEEE 754浮点加法乘法特殊规则](IEEE754浮点加法乘法特殊规则.md#一加法运算特殊值处理)
的基础上，根据FADD的各个修饰符含义进行处理。

FADD指令的求和结果可能产生NAN，这里着重指出NAN的处理规则：
- 如果启用了.SAT修饰符，则输出中的NAN被转换为0
- 否则，参考[浮点数NAN处理规则](浮点数NAN处理规则.md#32bit和16bit浮点数指令的处理规则)

  __Examples
```asm
FADD            R0,  R1 , -R2   ;  // R0 = R1 - R2
FADD.FTZ.SAT.RZ R0, |R1|, -0.25 ;  // R0 = clamp(|R1| - 0.25, 0, 1)
```

  __Simulation
      vd = fadd(va, vb);

__DefOpcode FADD_RR : [FADD]
  __Encoding
    field< 8,  4> SType stype == RR;

    field<32,  8> Reg rb;

    field<96,  1> SignModi rb.neg = False;
    field<97,  1> SignModi rb.abs = False;
  __OperandInfo
    InList<pg, ra, rb>;
    OutList<rd>;
    Order<pg, rd, ra, rb>;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<rd> = 32;

  __Exception


__DefOpcode FADD_RU : [FADD]
  __Encoding
    field< 8,  4> SType stype == RU;
    field<32,  6> UReg urb;
    field<96,  1> SignModi urb.neg = False;
    field<97,  1> SignModi urb.abs = False;
  __OperandInfo
    InList<pg, ra, urb>;
    OutList<rd>;
    Order<pg, rd, ra, urb>;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;
    Bitwidth<rd> = 32;

__DefOpcode FADD_RI : [FADD]
  __Encoding
    field< 8,  4> SType stype == RI;
    field<32, 32> F32Imm vb;
  __OperandInfo
    InList<pg, ra, vb>;
    OutList<rd>;
    Order<pg, rd, ra, vb>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rd> = 32;

__DefOpcode FADD_RC : [FADD]
  __Encoding
    field< 8,  4> SType stype == RC;
    field<32, 22> CMem vb;
    field<96,  1> SignModi vb.neg = False;
    field<97,  1> SignModi vb.abs = False;
  __OperandInfo
    InList<pg, ra, vb>;
    OutList<rd>;
    Order<pg, rd, ra, vb>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rd> = 32;

__DefOptype FMUL : [F_ARITH]
  __Encoding
    field< 0,  8> Optype optype == FMUL;
    field<80,  3> FMULScale scl = NoScale;

  __Syntax
```asm          
FMUL{.FTZ}{.SAT}{.rnd}{.scl} Rd, {-}{|}Ra{|}, {-}{|}SrcB{|}      $sched $req ;

.rnd = {.RN*, .RP, .RM, .RZ}
.scl = {.D2, .D4, .D8, .M2, .M4, .M8}
```

  __Description
执行2个输入浮点数的乘法，即Rd = Ra * SrcB。

  __OperandInfo
Ra和Rd必须来源于GPR。

SrcB的来源可以是GPR、UR、cmem或F32Imm。

  __ModifierInfo
.rnd可取.RN（默认值，可省略）、.RP、.RM和.RZ，表示计算结果的舍入模式：

| .rnd  | 舍入模式 |
|:--:|:---|
|.RN | 尾数四舍五入 |
|.RP | 尾数向正无穷方向舍入 |
|.RM | 尾数向负无穷方向舍入 |
|.RZ | 尾数向零（原点）舍入 |

可选修饰符.scl的取值包括.D2、.D4、.D8、.M2、.M4和.M8，表示在执行乘法之前对Ra预先进行的放缩操作：

| .scl | 对Ra执行的操作 |
|:--:|:--:|
| .D2 | ÷ 2 |
| .D4 | ÷ 4 |
| .D8 | ÷ 8 |
| .M2 | × 2 |
| .M4 | × 4 |
| .M8 | × 8 |

可选修饰符.FTZ表示如果输入/输出中有非规格化浮点数（subnormal number），则将其转换为有符号0（即保持符号位不变，其他bit全部置0）。

可选修饰符.SAT表示将结果截断到[+0.0, 1.0]的范围。

  __Semantics
```asm
FMUL.ftz.sat.rnd.scl Rd, Ra, SrcB:
    // 根据.FTZ启用与否，正确处理输入含非规格化浮点数的情况
    if (.ftz == .FTZ) {
        // 将输入的非规格化数flush到有符号0之后再参与比较
        if (isSubnormal(Ra) == true) {
            Ra = signZero(Ra);
        }
        if (isSubnormal(SrcB) == true) {
            SrcB = signZero(SrcB);
        }
    }
    // 根据.scl对Ra进行缩放
    a = scale(Ra, .scl);
    // 计算乘法
    t = a * SrcB;
    // 舍入到F32可表示的值
    Rd = roundToF32(t, .rnd);
    // 根据.sat，决定是否将输出饱和到[+0.0, 1.0]
    if (.sat == .SAT) {
        // NAN将被映射到0.0
        if (isNAN(Rd) == true) {
            Rd = 0.0f;
        } else {
            Rd = Rd < 0.0f ? 0.0f : Rd;
            Rd = Rd > 1.0f ? 1.0f : Rd;
        }
    } else if (isNAN(Rd) == true) {
        // 输出特殊的QNAN
        Rd[31:0] = 0x7FFFFFFF
    }
    // 正确处理输出中的非规格化数
    if (.ftz == .FTZ) {
        Rd = isSubnormal(Rd) ? signZero(Rd) : Rd;
    }
```

浮点乘法中的特殊值，在遵守
[IEEE 754浮点加法乘法特殊规则](IEEE754浮点加法乘法特殊规则.md#二乘法运算特殊值处理)
的基础上，根据各个修饰符含义进行处理。

FMUL指令的乘法结果可能产生NAN，这里着重指出NAN的处理规则：
- 如果启用了.SAT修饰符，则输出中的NAN被转换为0
- 否则，参考[浮点数NAN处理规则](浮点数NAN处理规则.md#32bit和16bit浮点数指令的处理规则)

  __Examples
```asm
FMUL               R0,  R1 , -R2        ;  // R0 = R1 * (-R2)
FMUL.FTZ.SAT.RZ.D2 R0, |R1|, 0f405A7EFA ;  // R0 ≈ clamp(|R1|/2*3.414, 0, 1)
```
  __Simulation
      vd = fmul(va, vb);

__DefOpcode FMUL_RR : [FMUL]
  __Encoding
    field< 8,  4> SType stype == RR;
    field<32,  8> Reg rb;
    field<96,  1> SignModi rb.neg = False;
    field<97,  1> SignModi rb.abs = False;
  __OperandInfo
    InList<pg, ra, rb>;
    OutList<rd>;
    Order<pg, rd, ra, rb>;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<rd> = 32;
  __Exception

__DefOpcode FMUL_RU : [FMUL]
  __Encoding
    field< 8,  4> SType stype == RU;
    field<32,  6> UReg urb;
    field<96,  1> SignModi urb.neg = False;
    field<97,  1> SignModi urb.abs = False;
  __OperandInfo
    InList<pg, ra, urb>;
    OutList<rd>;
    Order<pg, rd, ra, urb>;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;
    Bitwidth<rd> = 32;

__DefOpcode FMUL_RI : [FMUL]
  __Encoding
    field< 8,  4> SType stype == RI;
    field<32, 32> F32Imm vb;
  __OperandInfo
    InList<pg, ra, vb>;
    OutList<rd>;
    Order<pg, rd, ra, vb>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rd> = 32;

__DefOpcode FMUL_RC : [FMUL]
  __Encoding
    field< 8,  4> SType stype == RC;
    field<32, 22> CMem vb;
    field<96,  1> SignModi vb.neg = False;
    field<97,  1> SignModi vb.abs = False;
  __OperandInfo
    InList<pg, ra, vb>;
    OutList<rd>;
    Order<pg, rd, ra, vb>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rd> = 32;

__DefOptype FFMA : [F_ARITH]
  __Encoding
    field< 0,  8> Optype optype == FFMA;

  __Syntax
```asm          
FFMA{.FTZ}{.SAT}{.rnd} Rd, {-}{|}Ra{|}, {-}{|}SrcB{|}, {-}{|}SrcC{|}      $sched $req ;

.rnd = {.RN*, .RP, .RM, .RZ}
```

  __Description
执行3个输入浮点数的融合乘加运算，即Rd = Ra * SrcB + SrcC。

注意：Ra * SrcB的乘法是以全精度计算的，可以认为完全精确，乘积再与SrcC相加，最后舍入到F32的精度。

  __OperandInfo
Ra和Rd必须来源于GPR。

SrcB和SrcC的合法来源组合包括：

| SrcB | SrcC |
|:--:|:--:|
| GPR | GPR |
| GPR |F32Imm|
|F32Imm| GPR |
| GPR | UR  |
| UR  | GPR |
| GPR |cmem |
|cmem | GPR |

  __ModifierInfo
.rnd可取.RN（默认值，可省略）、.RP、.RM和.RZ，表示计算结果的舍入模式：

| .rnd  | 舍入模式 |
|:--:|:---|
|.RN | 尾数四舍五入 |
|.RP | 尾数向正无穷方向舍入 |
|.RM | 尾数向负无穷方向舍入 |
|.RZ | 尾数向零（原点）舍入 |

可选修饰符.FTZ表示如果输入/输出中有非规格化浮点数（subnormal number），则将其转换为有符号0（即保持符号位不变，其他bit全部置0）。

可选修饰符.SAT表示将结果截断到[+0.0, 1.0]的范围。

  __Semantics
```asm
FFMA.ftz.sat.rnd Rd, Ra, SrcB, SrcC:
    // 根据.FTZ启用与否，正确处理输入含非规格化浮点数的情况
    if (.ftz == .FTZ) {
        // 将输入的非规格化数flush到有符号0之后再参与比较
        if (isSubnormal(Ra) == true) {
            Ra = signZero(Ra);
        }
        if (isSubnormal(SrcB) == true) {
            SrcB = signZero(SrcB);
        }
    }
    // 计算乘法
    t = a * SrcB;
    // 计算加法
    Rd = t + SrcC;
    // 根据.sat，决定是否将输出饱和到[+0.0, 1.0]
    if (.sat == .SAT) {
        // NAN将被映射到0.0
        if (isNAN(Rd) == true) {
            Rd = 0.0f;
        } else {
            Rd = Rd < 0.0f ? 0.0f : Rd;
            Rd = Rd > 1.0f ? 1.0f : Rd;
        }
    } else if (isNAN(Rd) == true) {
        // 输出特殊的QNAN
        Rd[31:0] = 0x7FFFFFFF
    }
    // 正确处理输出中的非规格化数
    if (.ftz == .FTZ) {
        Rd = isSubnormal(Rd) ? signZero(Rd) : Rd;
    }
```

浮点乘加中的特殊值，在遵守
[IEEE 754浮点加法乘法特殊规则](IEEE754浮点加法乘法特殊规则.md)
的基础上，根据FFMA的各个修饰符含义进行处理。

FFMA指令的计算结果可能产生NAN，这里着重指出NAN的处理规则：
- 如果启用了.SAT修饰符，则输出中的NAN被转换为0
- 否则，参考[浮点数NAN处理规则](浮点数NAN处理规则.md#32bit和16bit浮点数指令的处理规则)

  __Exception

  __Examples
```asm
FFMA            R0,  R1,  -R2       , RZ             ; // R0 = R1 * (-R2)
FFMA.FTZ.SAT.RZ R0, |R1|, 0f405A7EFA, |c[0x0][0x100]|; // R0 = clamp(|R1|*3.414+|c[0x0][0x100]|, 0, 1)
```

  __Simulation
      vd = fmaf(va, vb, vc);

__DefOpcode FFMA_RRR : [FFMA]
  __Encoding
    field< 8,  4> SType stype == RRR;

    field<32,  8> Reg rb;
    field<64,  8> Reg rc;

    field<96,  1> SignModi rb.neg = False;
    field<97,  1> SignModi rb.abs = False;
    field<74,  1> SignModi rc.neg = False;
    field<75,  1> SignModi rc.abs = False;

  __Exception


  __OperandInfo
    InList<pg, ra, rb, rc>;
    OutList<rd>;
    Order<pg, rd, ra, rb, rc>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<rc> = 32;

__DefOpcode FFMA_RRI : [FFMA]
  __Encoding
    field< 8,  4> SType stype == RRI;

    field<32, 32> F32Imm vc;
    field<64,  8> Reg rb;

    field<74,  1> SignModi rb.neg = False;
    field<75,  1> SignModi rb.abs = False;

  __OperandInfo
    InList<pg, ra, rb, vc>;
    OutList<rd>;
    Order<pg, rd, ra, rb, vc>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<vc> = 32;

__DefOpcode FFMA_RIR : [FFMA]
  __Encoding
    field< 8,  4> SType stype == RIR;

    field<32, 32> F32Imm vb;
    field<64,  8> Reg rc;

    field<74,  1> SignModi rc.neg = False;
    field<75,  1> SignModi rc.abs = False;

  __OperandInfo
    InList<pg, ra, vb, rc>;
    OutList<rd>;
    Order<pg, rd, ra, vb, rc>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rc> = 32;

__DefOpcode FFMA_RRU : [FFMA]
  __Encoding
    field< 8,  4> SType stype == RRU;

    field<32,  6> UReg urc;
    field<64,  8> Reg rb;

    field<96,  1> SignModi urc.neg = False;
    field<97,  1> SignModi urc.abs = False;
    field<74,  1> SignModi rb.neg = False;
    field<75,  1> SignModi rb.abs = False;

  __OperandInfo
    InList<pg, ra, rb, urc>;
    OutList<rd>;
    Order<pg, rd, ra, rb, urc>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<urc> = 32;

__DefOpcode FFMA_RUR : [FFMA]
  __Encoding
    field< 8,  4> SType stype == RUR;

    field<32,  6> UReg urb;
    field<64,  8> Reg rc;

    field<96,  1> SignModi urb.neg = False;
    field<97,  1> SignModi urb.abs = False;
    field<74,  1> SignModi rc.neg = False;
    field<75,  1> SignModi rc.abs = False;

  __OperandInfo
    InList<pg, ra, urb, rc>;
    OutList<rd>;
    Order<pg, rd, ra, urb, rc>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;
    Bitwidth<rc> = 32;

__DefOpcode FFMA_RRC : [FFMA]
  __Encoding
    field< 8,  4> SType stype == RRC;

    field<32, 22> CMem vc;

    field<64,  8> Reg rb;

    field<96,  1> SignModi vc.neg = False;
    field<97,  1> SignModi vc.abs = False;
    field<74,  1> SignModi rb.neg = False;
    field<75,  1> SignModi rb.abs = False;

  __OperandInfo

    InList<pg, ra, rb, vc>;
    OutList<rd>;
    Order<pg, rd, ra, rb, vc>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<vc> = 32;

__DefOpcode FFMA_RCR : [FFMA]
  __Encoding
    field< 8,  4> SType stype == RCR;

    field<32, 22> CMem vb;

    field<64,  8> Reg rc;

    field<96,  1> SignModi vb.neg = False;
    field<97,  1> SignModi vb.abs = False;
    field<74,  1> SignModi rc.neg = False;
    field<75,  1> SignModi rc.abs = False;

  __OperandInfo
    InList<pg, ra, vb, rc>;
    OutList<rd>;
    Order<pg, rd, ra, vb, rc>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rc> = 32;

__DefOptype FMNMX : [FALU]
  __Encoding
    field< 0,  8> Optype optype == FMNMX;
    field<16,  8> Reg rd;

    field<98, 3> Pred pp;
    field<101, 1> PModi pp.not=False;

    field<24,  8> Reg ra;

    field<72,  1> SignModi ra.neg = False;
    field<73,  1> SignModi ra.abs = False;

    field<76,  1> FPFtz ftz = NoFTZ;
    field<83,  1> NAN nan = NoNAN;

  __Syntax
```asm
FMNMX{.FTZ}{.NAN} Rd, {-}{|}Ra{|}, {-}{|}SrcB{|}, {!}pp      $sched $req ;
```

  __Description
选取输入F32浮点数的最大/最小值输出。

  __OperandInfo
Rd和Ra必须来源于GPR。

SrcB可以来源于GPR、UR、F32Imm或cmem。

Ra和SrcB可以添加一个负号（-）前缀，表示取来源的相反数作为操作数。

Ra和SrcB也可以添加绝对值符号，表示取来源的绝对值作为操作数。
但如果SrcB来源于F32Imm，由于其值完全是字面上的，此时不再需要使用绝对值符号。

同时存在多种修饰符时，按照：先取绝对值，再取相反数的优先级次序结合。

pp必须来源于PR，且可以添加一个逻辑非（!）前缀，表示取反作为操作数。

  __ModifierInfo
可选修饰符.FTZ表示如果输入中出现了非规格化浮点数（subnormal number），则将其转换为有符号0（即保持符号位不变，其他bit全部置0）。

可选修饰符.NAN表示如果输入Ra和SrcB中有至少1个NAN，则输出固定为0x7FFFFFFF（符号位为0，其余为1）。

不启用.NAN修饰符时，对于输入含NAN的情况：
- 如果Ra和SrcB中有且仅有1个NAN，则输出为非NAN的那个数
- 如果Ra和SrcB都是NAN，则输出为0x7FFFFFFF

  __Semantics
注：若参与比较的2个输入绝对值均为0.0，则按照+0.0 > -0.0选取输出。

```asm
FMNMX.ftz.nan Rd, Ra, SrcB, pp:
    // 根据.NAN启用与否，正确处理输入含NAN的情况
    if (isNAN(Ra) == true || isNAN(SrcB) == true) {
        if (.nan == .NAN) {
            // 输出0x7FFFFFFF
            Rd[31:0] = 0x7FFFFFFF;
        } else if (isNAN(Ra) == false) {
            Rd = Ra;
        } else if (isNAN(SrcB) == false) {
            Rd = SrcB;
        } else {
            // 输入都是NAN，输出0x7FFFFFFF
            Rd[31:0] = 0x7FFFFFFF;
        }
    } else {
        // 根据.FTZ启用与否，正确处理输入含非规格化浮点数的情况
        if (.ftz == .FTZ) {
            if (isSubnormal(Ra) == true) {
                Ra = signZero(Ra);
            }
            if (isSubnormal(SrcB) == true) {
                SrcB = signZero(SrcB);
            }
        }
        // 根据pp，选择Ra和SrcB中较小/较大的那个作为输出
        Rd = pp ? min(Ra, SrcB) : max(Ra, SrcB);
    }
```
  __Exception

  __Examples
```asm
FMNMX R0, -|R1|, -|R2|, !PT;
FMNMX R0,   R1 ,     1,  P0;
FMNMX R0,   R1 , 0.125, !P1;
```
__DefOpcode FMNMX_RR : [FMNMX]
  __Encoding
    field< 8,  4> SType stype == RR;

    field<32,  8> Reg rb;

    field<96,  1> SignModi rb.neg = False;
    field<97,  1> SignModi rb.abs = False;
  __OperandInfo
    InList<pg, ra, rb, pp>;
    OutList<rd>;
    Order<pg, rd, ra, rb, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<rd> = 32;

__DefOpcode FMNMX_RU : [FMNMX]
  __Encoding
    field< 8,  4> SType stype == RU;

    field<32,  6> UReg urb;

    field<96,  1> SignModi urb.neg = False;
    field<97,  1> SignModi urb.abs = False;
  __OperandInfo
    InList<pg, ra, urb, pp>;
    OutList<rd>;
    Order<pg, rd, ra, urb, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;
    Bitwidth<rd> = 32;

__DefOpcode FMNMX_RI : [FMNMX]
  __Encoding
    field< 8,  4> SType stype == RI;
    field<32, 32> F32Imm vb;
  __OperandInfo
    InList<pg, ra, vb, pp>;
    OutList<rd>;
    Order<pg, rd, ra, vb, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rd> = 32;

__DefOpcode FMNMX_RC : [FMNMX]
  __Encoding
    field< 8,  4> SType stype == RC;
    field<32, 22> CMem vb;
    field<96,  1> SignModi vb.neg = False;
    field<97,  1> SignModi vb.abs = False;
  __OperandInfo
    InList<pg, ra, vb, pp>;
    OutList<rd>;
    Order<pg, rd, ra, vb, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rd> = 32;

__DefOptype FSETP : [FALU]
  __Encoding
    field< 0,  8> Optype optype == FSETP;

    field<98, 3> Pred pp = PT;
    field<101, 1> PModi pp.not=False;
    field<106, 3> Pred pu;
    field<109, 3> Pred pv = PT;

    field<76,  1> FPFtz ftz = NoFTZ;

    field<24,  8> Reg ra;
    field<72,  1> SignModi ra.neg = False;
    field<73,  1> SignModi ra.abs = False;

    field<84,  2> LOPOp lop;
    field<86,  4> FCMPOp cmp;

  __Syntax
```asm          
FSETP{.FTZ}.cmp.lop pu, {pv,} {-}{|}Ra{|}, {-}{|}SrcB{|}{, {!}pp}      $sched $req ;

.cmp = {.EQ, .NE, .LT, .LE, .GT, .GE, .EQU, .NEU, .LTU, .LEU, .GTU, .GEU, .NAN, .NUM}
.lop = {.AND, .OR, .XOR}
```

  __Description
对2个输入浮点数进行指定的算术比较，将比较结果（布尔值）与一个额外的输入谓词进行指定的布尔运算，得到输出。

  __OperandInfo
Ra只能来源于GPR。

SrcB可以是GPR、UR、F32Imm或cmem。

Ra和SrcB可以添加一个负号（-）前缀，表示取来源的相反数作为操作数。

Ra和SrcB也可以添加绝对值符号，表示取来源的绝对值作为操作数。
但如果SrcB来源于F32Imm，由于其值完全是字面上的，此时不再需要使用绝对值符号。

同时存在多种修饰符时，按照：先取绝对值，再取相反数的优先级次序结合。

输出操作数pu、pv，输入操作数pp均为谓词，来源只能是PR。

输出操作数pv的默认值是PT（可以省略），表示舍弃pv的计算结果。

输入操作数pp的默认值是PT（可以省略），且可添加一个逻辑非(!)前缀，表示取反作为操作数。

  __ModifierInfo
.cmp决定对Ra、SrcB所作的算术比较，包含14种可取值。
按照对输入NAN时的处理方式，.cmp的前12种可取值被分为ordered比较和unordered比较两类：

| ordered比较 | unordered比较 | 输入不含NAN时的语义 |
|:--:|:--:|:--:|
| .EQ | .EQU | == |
| .NE | .NEU | != |
| .LT | .LTU | <  |
| .LE | .LEU | <= |
| .GT | .GTU | >  |
| .GE | .GEU | >= |

二者的区别在于，当比较的两个操作数中至少含有1个NAN时：
- ordered比较：返回false
- unordered比较：返回true

.cmp的最后2种可取值.NAN和.NUM的含义如下：
- .NAN：参与比较的2个输入至少一个是NAN时，结果为true，否则为false
- .NUM：参与比较的2个输入都不是NAN时，结果为true，否则为false

.lop决定了将Ra、SrcB的比较结果与输入布尔值（操作数pp）进行何种布尔运算：

| .lop | 功能 |
|:--:|:--:|
| .AND | && |
| .OR  | \|\| |
| .XOR | ^ |

可选修饰符.FTZ表示如果输入中有非规格化浮点数（subnormal number），则将其转换为有符号0（即保持符号位不变，其他bit全部置0）。

  __Semantics
```asm
FSETP.ftz.cmp.lop pu, pv, Ra, SrcB, pp:
    // 根据.FTZ启用与否，正确处理输入含非规格化浮点数的情况
    if (.ftz == .FTZ) {
        // 将输入的非规格化数flush到有符号0之后在参与比较
        if (isSubnormal(Ra) == true) {
            Ra = signZero(Ra);
        }
        if (isSubnormal(SrcB) == true) {
            SrcB = signZero(SrcB);
        }
    }
    // 比较2个输入操作数Ra与SrcB
    t = Ra cmp SrcB ? true : false;
    // 根据lop对t与pp进行布尔运算
    pu = t lop pp;
    pv = (!t) lop pp;
```

  __Examples
```asm
FSETP.LE.AND     P0,       R4 , R6,  PT;
FSETP.FTZ.GTU.OR P0, P1, -|R5|, -1, !PT;
```

__DefOpcode FSETP_RR : [FSETP]
  __Encoding
    field< 8,  4> SType stype == RR;
    field<32,  8> Reg rb;
    field<96,  1> SignModi rb.neg = False;
    field<97,  1> SignModi rb.abs = False;
  __OperandInfo
    InList<pg, ra, rb, pp>;
    OutList<pu, pv>;
    Order<pg, pu, pv, ra, rb, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;

__DefOpcode FSETP_RU : [FSETP]
  __Encoding
    field< 8,  4> SType stype == RU;
    field<32,  6> UReg urb;
    field<96,  1> SignModi urb.neg = False;
    field<97,  1> SignModi urb.abs = False;
  __OperandInfo
    InList<pg, ra, urb, pp>;
    OutList<pu, pv>;
    Order<pg, pu, pv, ra, urb, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;

__DefOpcode FSETP_RI : [FSETP]
  __Encoding
    field< 8,  4> SType stype == RI;
    field<32, 32> F32Imm vb;
  __OperandInfo
    InList<pg, ra, vb, pp>;
    OutList<pu, pv>;
    Order<pg, pu, pv, ra, vb, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;

__DefOpcode FSETP_RC : [FSETP]
  __Encoding
    field< 8,  4> SType stype == RC;
    field<32, 22> CMem vb;
    field<96,  1> SignModi vb.neg = False;
    field<97,  1> SignModi vb.abs = False;
  __OperandInfo
    InList<pg, ra, vb, pp>;
    OutList<pu, pv>;
    Order<pg, pu, pv, ra, vb, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;

__DefOptype FSET : [FALU]
  __Encoding
    field< 0,  8> Optype optype == FSET;

    field<98, 3> Pred pp = PT;
    field<101, 1> PModi pp.not=False;

    field<76,  1> FPFtz ftz = NoFTZ;

    field<16,  8> Reg rd;
    field<24,  8> Reg ra;
    field<72,  1> SignModi ra.neg = False;
    field<73,  1> SignModi ra.abs = False;

    field<84,  2> LOPOp lop;
    field<86,  4> FCMPOp cmp;
    field<90,  1> BVal bval = BM;

  __Syntax
```asm          
FSET{.FTZ}.cmp.lop{.bval} Rd, {-}{|}Ra{|}, {-}{|}SrcB{|}, {!}pp      $sched $req ;

.cmp = {.EQ, .NE, .LT, .LE, .GT, .GE, .EQU, .NEU, .LTU, .LEU, .GTU, .GEU, .NAN, .NUM}
.lop = {.AND, .OR, .XOR}
.bval = {.BM*, .BF}
```

  __Description
对2个输入浮点数进行指定的算术比较，将比较结果（布尔值）与一个额外的输入谓词进行指定的布尔运算，得到输出。

  __OperandInfo
Ra和Rd必须来源于GPR。

SrcB的来源可以是GPR、UR、F32Imm或cmem。

Ra和SrcB可以添加一个负号（-）前缀，表示取来源的相反数作为操作数。

Ra和SrcB也可以添加绝对值符号，表示取来源的绝对值作为操作数。
但如果SrcB来源于F32Imm，由于其值完全是字面上的，此时不再需要使用绝对值符号。

同时存在多种修饰符时，按照：先取绝对值，再取相反数的优先级次序结合。

输入操作数pp只能来源于PR，可以添加一个逻辑非(!)前缀，表示取反作为操作数。pp的默认值是PT，此时可以省略。

  __ModifierInfo
.cmp决定对Ra、SrcB所作的算术比较，包含14种可取值。
按照对输入NAN时的处理方式，.cmp的前12种可取值被分为ordered比较和unordered比较两类：

| ordered比较 | unordered比较 | 输入不含NAN时的语义 |
|:--:|:--:|:--:|
| .EQ | .EQU | == |
| .NE | .NEU | != |
| .LT | .LTU | <  |
| .LE | .LEU | <= |
| .GT | .GTU | >  |
| .GE | .GEU | >= |

二者的区别在于，当比较的两个操作数中至少含有1个NAN时：
- ordered比较  ：返回false
- unordered比较：返回true

.cmp的最后2种可取值.NAN和.NUM的含义如下：
- .NAN：参与比较的2个输入至少一个是NAN时，结果为true，否则为false
- .NUM：参与比较的2个输入都不是NAN时，结果为true，否则为false

.lop决定了将Ra、SrcB的比较结果与输入布尔值（操作数pp）进行何种布尔运算：

| .lop | 功能 |
|:--:|:--:|
| .AND | && |
| .OR  | \|\| |
| .XOR | ^ |

.bval可取值为.BM（默认，可省略）或.BF，用于决定最终布尔运算的结果（布尔值）如何转换为输出操作数Rd的32bit寄存器值：

|    | .BM | .BF |
|:--:|:--|:--|
| 结果为true  | 0xFFFFFFFF  | 0x3F800000  |
| 结果为false | 0x00000000  | 0x00000000  |

可选修饰符.FTZ表示如果输入中有非规格化浮点数（subnormal number），则将其转换为有符号0（即保持符号位不变，其他bit全部置0）。

  __Semantics
```asm
FSETP.ftz.cmp.lop.bval Rd, Ra, SrcB, pp:
    // 根据.FTZ启用与否，正确处理输入含非规格化浮点数的情况
    if (.ftz == .FTZ) {
        // 将输入的非规格化数flush到有符号0之后在参与比较
        if (isSubnormal(Ra) == true) {
            Ra = signZero(Ra);
        }
        if (isSubnormal(SrcB) == true) {
            SrcB = signZero(SrcB);
        }
    }
    // 比较2个输入操作数Ra与SrcB
    t = Ra cmp SrcB ? true : false;
    // 将比较结果与pp进行布尔运算后，转换为32bit输出
    if (.bval == .BM)
        Rd = (t lop pp) ? 0xFFFFFFFF : 0x00000000;
    else
        Rd = (t lop pp) ? 0x3F800000 : 0x00000000; // 0x3F800000 即为1.0f
```

  __Exception

  __Examples
```asm
FSET.LE.AND       R0,  R4,  R6     ;
FSET.FTZ.GT.OR.BF R0, -R5, -34, P0 ;
```

__DefOpcode FSET_RR : [FSET]
  __Encoding
    field< 8,  4> SType stype == RR;
    field<32,  8> Reg rb;
    field<96,  1> SignModi rb.neg = False;
    field<97,  1> SignModi rb.abs = False;
  __OperandInfo
    InList<pg, ra, rb, pp>;
    OutList<rd>;
    Order<pg, rd, ra, rb, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<rd> = 32;

__DefOpcode FSET_RU : [FSET]
  __Encoding
    field< 8,  4> SType stype == RU;
    field<32,  6> UReg urb;
    field<96,  1> SignModi urb.neg = False;
    field<97,  1> SignModi urb.abs = False;
  __OperandInfo
    InList<pg, ra, urb, pp>;
    OutList<rd>;
    Order<pg, rd, ra, urb, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;
    Bitwidth<rd> = 32;

__DefOpcode FSET_RI : [FSET]
  __Encoding
    field< 8,  4> SType stype == RI;
    field<32, 32> F32Imm vb;
  __OperandInfo
    InList<pg, ra, vb, pp>;
    OutList<rd>;
    Order<pg, rd, ra, vb, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rd> = 32;

__DefOpcode FSET_RC : [FSET]
  __Encoding
    field< 8,  4> SType stype == RC;
    field<32, 22> CMem vb;
    field<96,  1> SignModi vb.neg = False;
    field<97,  1> SignModi vb.abs = False;
  __OperandInfo
    InList<pg, ra, vb, pp>;
    OutList<rd>;
    Order<pg, rd, ra, vb, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rd> = 32;

__DefOptype FSEL : [FALU]
  __Encoding
    field< 0,  8> Optype optype == FSEL;
    field<98, 3> Pred pp = PT;
    field<101, 1> PModi pp.not = False;
    field<16,  8> Reg rd;
    field<24,  8> Reg ra;
    field<72,  1> SignModi ra.neg = False;
    field<73,  1> SignModi ra.abs = False;
    field<76,  1> FPFtz ftz = NoFTZ;

  __Syntax
```asm          
FSEL{.FTZ} Rd, {-}{|}Ra{|}, {-}{|}SrcB{|}, {!}pp      $sched $req ;
```

  __Description
根据谓词pp的值，选择将Ra或SrcB的值赋予给Rd。相当于C语言中的三元运算符。

  __OperandInfo
Rd和Ra来源于GPR。

SrcB的合法来源包括GPR、F32Imm、cmem和UR。

Ra和SrcB可以添加一个负号（-）前缀，表示取来源的相反数作为操作数。

Ra和SrcB也可以添加绝对值符号，表示取来源的绝对值作为操作数。
但如果SrcB来源于F32Imm，由于其值完全是字面上的，此时不再需要使用绝对值符号。

同时存在多种修饰符时，按照：先取绝对值，再取相反数的优先级次序结合。

pp来源于PR（默认值为PT，可省略），可以带有一个逻辑非修饰符（!），表示对来源取反作为操作数。

  __ModifierInfo
可选修饰符.FTZ表示如果输入有非规格化浮点数（subnormal number），则将其转换为有符号0（即保持符号位不变，其他bit全部置0）。

  __Semantics
```asm
FSEL.ftz Rd, Ra, SrcB, pp:
    // 根据.FTZ启用与否，正确处理输入含非规格化浮点数的情况
    if (.ftz == .FTZ) {
        // 将输入的非规格化数flush到有符号0之后在参与比较
        if (isSubnormal(Ra) == true) {
            Ra = signZero(Ra);
        }
        if (isSubnormal(SrcB) == true) {
            SrcB = signZero(SrcB);
        }
    }
    // 根据pp选择输出
    Rd = pp ? Ra : SrcB;
```

  __Exception

  __Examples
```asm
FSEL.FTZ R0, R1, R2, !P0;
```

__DefOpcode FSEL_RR : [FSEL]
  __Encoding
    field< 8,  4> SType stype == RR;

    field<32,  8> Reg rb;

    field<96,  1> SignModi rb.neg = False;
    field<97,  1> SignModi rb.abs = False;
  __OperandInfo
    InList<pg, ra, rb, pp>;
    OutList<rd>;
    Order<pg, rd, ra, rb, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<rd> = 32;

__DefOpcode FSEL_RU : [FSEL]
  __Encoding
    field< 8,  4> SType stype == RU;
    field<32,  6> UReg urb;
    field<96,  1> SignModi urb.neg = False;
    field<97,  1> SignModi urb.abs = False;
  __OperandInfo
    InList<pg, ra, urb, pp>;
    OutList<rd>;
    Order<pg, rd, ra, urb, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;
    Bitwidth<rd> = 32;

__DefOpcode FSEL_RI : [FSEL]
  __Encoding
    field< 8,  4> SType stype == RI;
    field<32, 32> F32Imm vb;
  __OperandInfo
    InList<pg, ra, vb, pp>;
    OutList<rd>;
    Order<pg, rd, ra, vb, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rd> = 32;

__DefOpcode FSEL_RC : [FSEL]
  __Encoding
    field< 8,  4> SType stype == RC;
    field<32, 22> CMem vb;
    field<96,  1> SignModi vb.neg = False;
    field<97,  1> SignModi vb.abs = False;
  __OperandInfo
    InList<pg, ra, vb, pp>;
    OutList<rd>;
    Order<pg, rd, ra, vb, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rd> = 32;

__DefOptype FCHK : [FALU]
  __Encoding
    field< 0,  8> Optype optype == FCHK;
    field<106, 3> Pred pu;
    field<24,  8> Reg ra;
    field<72,  1> SignModi ra.neg = False;
    field<73,  1> SignModi ra.abs = False;

  __Syntax
```asm          
FCHK pu, {-}{|}Ra{|}, {-}{|}SrcB{|}      $sched $req ;
```

  __Description
该指令用于提供软件实现的浮点数乘法所需的除数、被除数检查。检查结果是一个布尔值，通过谓词寄存器输出。

  __OperandInfo
Ra来源于GPR。

SrcB的合法来源包括GPR、F32Imm、cmem和UR。

Ra和SrcB可以添加一个负号（-）前缀，表示取来源的相反数作为操作数。

Ra和SrcB也可以添加绝对值符号，表示取来源的绝对值作为操作数。
但如果SrcB来源于F32Imm，由于其值完全是字面上的，此时不再需要使用绝对值符号。

同时存在多种修饰符时，按照：先取绝对值，再取相反数的优先级次序结合。

输出结果pu必须是PR谓词寄存器。

  __Semantics
```asm
FCHK pu, Ra, SrcB:
    // 解析F32浮点数Ra和SrcB的无偏指数部分：
    ea = extractUnbiasedExp(Ra);
    eb = extractUnbiasedExp(SrcB);
    // IEEE-754 F32浮点数规格：
    emin = -126;    // 最小无偏指数
    emax = 127;     // 最大无偏指数
    N = 23;         // 23位尾数
    // 执行比较：
    pu = (ea <= emin + N)      ||
         (ea >= emax + 1)      ||
         (eb <= emin)          ||
         (eb >= emax - 2)      ||
         (ea - eb <= emin + 1) ||
         (ea - eb >= emax)      ? true : false;
```

对F32浮点数而言，所谓无偏指数部分，指的是31:24位的8bit指数减去偏移127：
```asm
extractUnbiasedExp(F32):
  return (F32[31:24] - 127);
```

  __Examples
```asm
FCHK P0,   R2 ,  R3 ;
FCHK P0,  -R7 , |R3|;
FCHK P0, -|R4|,  R1 ;
```

__DefOpcode FCHK_RR : [FCHK]
  __Encoding
    field< 8,  4> SType stype == RR;
    field<32,  8> Reg rb;
    field<96,  1> SignModi rb.neg = False;
    field<97,  1> SignModi rb.abs = False;
  __OperandInfo
    InList<pg, ra, rb>;
    OutList<pu>;
    Order<pg, pu, ra, rb>;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;

__DefOpcode FCHK_RU : [FCHK]
  __Encoding
    field< 8,  4> SType stype == RU;
    field<32,  6> UReg urb;
    field<96,  1> SignModi urb.neg = False;
    field<97,  1> SignModi urb.abs = False;
  __OperandInfo
    InList<pg, ra, urb>;
    OutList<pu>;
    Order<pg, pu, ra, urb>;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;

__DefOpcode FCHK_RI : [FCHK]
  __Encoding
    field< 8,  4> SType stype == RI;
    field<32, 32> F32Imm vb;
  __OperandInfo
    InList<pg, ra, vb>;
    OutList<pu>;
    Order<pg, pu, ra, vb>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;

__DefOpcode FCHK_RC : [FCHK]
  __Encoding
    field< 8,  4> SType stype == RC;
    field<32, 22> CMem vb;
    field<96,  1> SignModi vb.neg = False;
    field<97,  1> SignModi vb.abs = False;
  __OperandInfo
    InList<pg, ra, vb>;
    OutList<pu>;
    Order<pg, pu, ra, vb>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;